<script lang="ts" setup>
// TODO @芋艿：是否有更好的组织形式？！
// TODO @xingyu：你感觉，这个放到每个 system、infra 模块下，然后新建一个 components，表示每个模块，有一些共享的组件？然后，全局只放通用的（无业务含义的），可以哇？
import type { SystemDeptApi } from '#/api/system/dept';
import type { SystemUserApi } from '#/api/system/user';

import { ref } from 'vue';

import { useVbenModal } from '@vben/common-ui';
import { handleTree } from '@vben/utils';

import { ElButton, ElMessage } from 'element-plus';

import { getSimpleDeptList } from '#/api/system/dept';
import { getUserPage } from '#/api/system/user';
// 部门树节点接口
interface DeptTreeNode {
  key: string;
  label: string;
  children?: DeptTreeNode[];
  name: string;
}

defineOptions({ name: 'UserSelectModal' });

withDefaults(
  defineProps<{
    cancelText?: string;
    confirmText?: string;
    multiple?: boolean;
    value?: number[];
  }>(),
  {
    multiple: true,
    value: () => [],
    confirmText: '确定',
    cancelText: '取消',
  },
);

const emit = defineEmits<{
  cancel: [];
  closed: [];
  confirm: [value: SystemUserApi.User[]];
  'update:value': [value: number[]];
}>();

// 部门树数据
const deptTree = ref<any[]>([]);
const deptList = ref<SystemDeptApi.Dept[]>([]);
const expandedKeys = ref<string[]>([]);
const selectedDeptId = ref<number>();
const deptSearchKeys = ref('');

// 用户数据管理
const userList = ref<SystemUserApi.User[]>([]); // 存储所有已知用户
const selectedUserIds = ref<string[]>([]);

// 弹窗配置
const [Modal, modalApi] = useVbenModal({
  onCancel: handleCancel,
  onClosed: handleClosed,
  async onOpenChange(isOpen: boolean) {
    if (!isOpen) {
      resetData();
      return;
    }
    // 加载数据
    const data = modalApi.getData();
    if (!data) {
      return;
    }
    modalApi.lock();
    try {
      // 加载部门数据
      const deptData = await getSimpleDeptList();
      deptList.value = deptData;
      const treeData = handleTree(deptData);
      deptTree.value = treeData.map((node) => processDeptNode(node));
      expandedKeys.value = deptTree.value.map((node) => node.key);

      // 设置已选用户
      if (data.userIds?.length) {
        selectedUserIds.value = data.userIds.map(String);
        // 加载已选用户的完整信息  TODO   目前接口暂不支持 多个用户ID 查询， 需要后端支持
        const { list } = await getUserPage({
          pageNo: 1,
          pageSize: 100, // 临时使用固定值确保能加载所有已选用户
          userIds: data.userIds,
        });
        // 使用 Map 来去重，以用户 ID 为 key
        const userMap = new Map(userList.value.map((user) => [user.id, user]));
        list.forEach((user) => {
          if (!userMap.has(user.id)) {
            userMap.set(user.id, user);
          }
        });
        userList.value = [...userMap.values()];
      }

      modalApi.open();
    } finally {
      modalApi.unlock();
    }
  },
  destroyOnClose: true,
});
// 确认选择
function handleConfirm() {
  if (selectedUserIds.value.length === 0) {
    ElMessage.warning('请选择用户');
    return;
  }
  emit(
    'confirm',
    userList.value.filter((user) =>
      selectedUserIds.value.includes(String(user.id)),
    ),
  );
  modalApi.close();
}

// 取消选择
function handleCancel() {
  emit('cancel');
  modalApi.close();
  // 确保在动画结束后再重置数据
  setTimeout(() => {
    resetData();
  }, 300);
}

// 关闭弹窗
function handleClosed() {
  emit('closed');
  resetData();
}
// 重置数据
function resetData() {
  userList.value = [];
  selectedUserIds.value = [];
  // 取消部门选中
  selectedDeptId.value = undefined;

  // 取消选中的用户
  selectedUserIds.value = [];
}

// 递归处理部门树节点
function processDeptNode(node: any): DeptTreeNode {
  return {
    key: String(node.id),
    label: `${node.name} (${node.id})`,
    name: node.name,
    children: node.children?.map((child: any) => processDeptNode(child)),
  };
}
</script>
<template>
  <Modal class="w-2/5" key="user-select-modal" :title="title">
    <template #footer>
      <ElButton
        type="primary"
        :disabled="selectedUserIds.length === 0"
        @click="handleConfirm"
      >
        {{ confirmText }}
      </ElButton>
      <ElButton @click="handleCancel">{{ cancelText }}</ElButton>
    </template>
  </Modal>
</template>
